// -------------------------------------------------------------------------------------
// ExpandedView.m
// Martin D. Flynn, NeXT Computer, Inc.
// You may freely copy, distribute and reuse the code in this example.
// NeXT disclaims any warranty of any kind, expressed or implied, as to its
// fitness for any particular use.
// -------------------------------------------------------------------------------------

#import <stdlib.h>
#import <stdio.h>
#import <string.h>
#import <math.h>
#import <libc.h>
#import <sys/time.h>
#import <defaults/defaults.h>
#import <appkit/graphics.h>
#import <appkit/Panel.h>
#import <appkit/NXImage.h>
#import <appkit/NXBitmapImageRep.h>
#import <appkit/NXEPSImageRep.h>
#import <appkit/ScrollView.h>
#import <dpsclient/psops.h>
#import <dpsclient/dpsNeXT.h>
#import <objc/objc-runtime.h>
#import "ExpandedView.h"

// -------------------------------------------------------------------------------------
#define	minWIDTH	48.0
#define	minHEIGHT	48.0

@implementation ExpandedView

// -------------------------------------------------------------------------------------
// create a new instance

/* standard init */
- initFrame:(const NXRect *)frameRect
{
	[super initFrame:frameRect];
	imageId = (id)nil;
	return self;
}

/* init from scroll view */
- setScrollView:scrollView
{
	myScrollView = scrollView;
	return self;
}

// -------------------------------------------------------------------------------------
// image methods

/* set image */
- setImage:image
{
	NXRect	vFrame;
	id		rep;
  
	/* check for valid image representation */
	if (!(imageId=(image&&[[image representationList] count])?image:(id)nil)) return self;
  
	/* resize view to match image */
	[imageId getSize:&imageFrame.size];
	vFrame.origin.x = vFrame.origin.y = 0.0;
	vFrame.size = imageFrame.size;
	if (vFrame.size.width  < minWIDTH ) vFrame.size.width  = minWIDTH ;
	if (vFrame.size.height < minHEIGHT) vFrame.size.height = minHEIGHT;
	[self setFrame:&vFrame];
	drawWithAlpha = YES;
  
	/* center image in view */
	imageFrame.origin.x = (bounds.size.width  - imageFrame.size.width ) / 2.0;
	imageFrame.origin.y = (bounds.size.height - imageFrame.size.height) / 2.0;
  
	/* set defaqult background gray value */
	imageRep = 0;
	rep = [[imageId representationList] objectAt:imageRep];
	backgroundGray = ([rep isKindOf:[NXEPSImageRep class]])? NX_WHITE : NX_LTGRAY;

	return self;
}

// -------------------------------------------------------------------------------------
// mouse down

- mouseDown:(NXEvent*)e
{
	if (!imageId) return self;
	if ((e->flags) & NX_ALTERNATEMASK) {
		if (drawWithAlpha) { imageRep = 0; drawWithAlpha = NO; }
		else imageRep = (++imageRep) % [[imageId representationList] count];
	} else {
		if (drawWithAlpha) return self;
		drawWithAlpha = YES;
	}
	[self display];
	return self;
}

// -------------------------------------------------------------------------------------
// draw methods

/* draw self */
- drawSelf:(const NXRect *)r :(int)c
{
	PSsetgray((imageId)?backgroundGray:NX_LTGRAY);
	NXRectFill(&bounds);
	if (imageId) {
		if (drawWithAlpha) [imageId composite:NX_SOVER toPoint:&imageFrame.origin];
		else {
			id repList = [imageId representationList];
			id rep = [repList objectAt:imageRep % [repList count]];
			[rep drawIn:&imageFrame];
		}
	}
	return self;
}

// -------------------------------------------------------------------------------------
// expanded image window delegate methods

/* window is resizing */
- windowWillResize:windowId toSize:(NXSize*)newSize
{
	NXRect	fRect, cRect;
	NXSize	cSize = imageFrame.size;
  
	/* get scroll frame size */
	cSize.width  = MAX(imageFrame.size.width , minWIDTH );
	cSize.height = MAX(imageFrame.size.height, minHEIGHT);
	[ScrollView getFrameSize:&cRect.size forContentSize:&cSize
  			 horizScroller:YES vertScroller:YES borderType:[myScrollView borderType]];

	/* get window frame size */
	cRect.origin.x = cRect.origin.y = 0.0;
	[Window getFrameRect:&fRect forContentRect:&cRect style:[windowId style]];

	/* limit size */
	if (newSize->width  > fRect.size.width ) newSize->width  = fRect.size.width ;
	if (newSize->height > fRect.size.height) newSize->height = fRect.size.height;

	return self;
}

/* window is resizing */
- windowDidResize:windowId
{
	NXRect	fRect, cRect;
  
	/* get window content sizer */
	[windowId getFrame:&fRect];
	[Window getContentRect:&cRect forFrameRect:&fRect style:[windowId style]];
  
	/* set scroller */
	cRect.origin.x = cRect.origin.y = 0.0;
	[myScrollView setFrame:&cRect];
	[myScrollView setHorizScrollerRequired:YES];
	[myScrollView setVertScrollerRequired:YES];
  
	return self;
}

@end
